// import * as PIXI from "pixi.js";
// import {
//   getGoalData,
//   absolutePath
// } from "../../utils/index";
// import { PreTreatmentResult, Scope } from "../../typings/traverse";
// import {
//   disposeInteractive,
//   disposeBasic
// } from "../Directives/index";
// import { PixijsvueComponentConfig } from "../../typings/main";
// import { preTreatment } from "./lib/preTreatment";
// import { bindDataToSub, getComponentConfig, initComponentConfig, getListeners } from "./lib/dealWithContainer";

// function dealWithContainer(
//   this: PixijsvueComponent,
//   ele: Element,
//   scope?: Scope
// ) {
//   const {$data, $watcher} = this;
//   let container: PIXI.Container = new PIXI.Container();
//   this.$directives.bind(container, ele, scope);
//   let tagName = ele.tagName.toLowerCase();
//   let PixijsvueComponentConfig: PixijsvueComponentConfig | undefined;
//   // slot 处理
//   if (tagName == "slot") {
//     if (this.$slot) {
//       return this.$slot;
//     }
//   }
//   // component 处理 (局部组件可以覆盖全局组件)
//   PixijsvueComponentConfig = getComponentConfig({ components: this.$options.components, _globalComponents: this.$root._globalComponents}, tagName);
//   if (PixijsvueComponentConfig) {
//     let config = initComponentConfig({_data: this._data},PixijsvueComponentConfig, ele, scope);
//     // slot
//     let slot: PIXI.Container | undefined;
//     if (ele.children.length > 0) {
//       slot = new PIXI.Container();
//       Object.values(ele.children).forEach((_ele) => {
//         slot!.addChild(forEachCom.call(this, _ele, scope));
//       });
//       ele.innerHTML = "";
//     }
//     // listeners
//     let listeners = getListeners({ $data: this.$data, $methods: this.$methods}, ele, config.props, scope);
//     let pixijsvueComponent = new PixijsvueComponent(
//       config,
//       this.$root,
//       this,
//       slot,
//       listeners
//     );
//     bindDataToSub({$watcher, $data, pixijsvueComponent}, ele, config.props, scope);
//     this.$children.push(pixijsvueComponent);
//     container = pixijsvueComponent.$vm;
//     disposeInteractive(
//       this,
//       this.$data,
//       this.$methods,
//       container,
//       ele,
//       scope,
//       true
//     );
//   } else {
//     disposeInteractive(
//       this,
//       this.$data,
//       this.$methods,
//       container,
//       ele,
//       scope,
//       false
//     );
//   }

//   let keyValue: string | number | undefined = undefined;
//   if (scope) {
//     // key 为item 或item.key
//     const { item, items, key } = scope;
//     if (key) {
//       keyValue = getGoalData(this.$data, absolutePath(items, item, key));
//       if (typeof keyValue != "number" && typeof keyValue != "string") {
//         throw new Error("v-for中v-key或:key必须为string或number类型");
//       }
//     }
//   }
//   let cb = () => {
//     disposeBasic(
//       this,
//       {
//         $data: this.$data,
//         $globalResource: this.$root.$globalResource,
//         $id: this.$id,
//         $resource: this.$resource,
//         $style: this.$style,
//         $watcher: this.$watcher,
//         _depList: this._depList,
//       },
//       container,
//       ele,
//       scope
//     );
//   };
//   this.$hook.addHooks("mounted", cb);
//   return container;
// }

// /**
//  *
//  * @param rootContainer 相对root，Container
//  * @param subEle root下的子元素
//  * @param containerStack
//  * @param elementStack
//  */
// function linkContainer(
//   this: PixijsvueComponent,
//   rootContainer: PIXI.Container,
//   subEle: Element,
//   containerStack: Array<PIXI.Container>,
//   elementStack: Array<Element>,
//   scope?: Scope
// ) {
//   let { $data, $watcher } = this;
//   let depName = "data";
//   let preTreatmentResult: PreTreatmentResult = preTreatment(
//     { $data },
//     subEle,
//     scope
//   );
//   const { element } = preTreatmentResult;

//   if (preTreatmentResult.v_for) {
//     let containerArray: Array<PIXI.Container> = [];
//     let firstChildSit: number;
//     let nowSit = 0;
//     const { item, items, key } = preTreatmentResult.v_for;
//     // length 是需要随着数组的长度发生变化的
//     let { length } = preTreatmentResult.v_for;
//     for (let i = 0; i < length; i++) {
//       /**
//        * 由于预处理v-for指令后，得到了，需要循环渲染的Container个数
//        * 和每个新Container的特有scope作用域。
//        * 所以就以预处理中去除v-for等指令的元素作为根元素，递归的调用forEach。
//        *
//        */
//       let container = forEachCom.call(this, element, {
//         item,
//         items: `${items}.${i}` /* 这里加上 .i 目的是其子元素调用getGoalData时，可以准确的获取该scope中的数据 */,
//         /**
//          * @example
//          * 在vue中
//          * <template>
//          *  <div>
//          *    <div v-for="item in items" :key="item">
//          *      <div v-text="item"></div>
//          *    </div>
//          *  </div>
//          * </template>
//          * v-text="item", 这里的item不是data中的item,而是v-for="item in items",中的item。
//          * 同理，`${items}.${i}`中加上i, 就是为了能从items中准确定位到对应的item
//          */
//         key /* TODO */,
//       });
//       rootContainer.addChild(container);
//       containerStack.push(container);

//       // 这里将v-for生成的container，保存起来，当proxy.arr执行sort之类对原数组
//       // 有影响的行为时，用来重新渲染所有container
//       containerArray.push(container);
//     }
//     // 记录头一个container的下标，这样无论这组连续的container在哪个位置
//     // 删除后，都可以根据这个下标，依次插入container，恢复原来的布局
//     firstChildSit = rootContainer.getChildIndex(containerArray[0]);
//     nowSit = firstChildSit;
//     let fun: Function = () => {
//       // 当使用push增加元素时，要重新确认length的值
//       length = getGoalData($data, items).length;
//       containerArray.forEach((container) => {
//         rootContainer.removeChild(container);
//       });
//       containerArray = [];
//       for (let i = 0; i < length; i++) {
//         containerArray.push(
//           forEachCom.call(this, element, {
//             item,
//             items: `${items}.${i}`,
//             key,
//           })
//         );
//       }
//       containerArray.forEach((container) => {
//         rootContainer.addChildAt(container, nowSit);
//         nowSit++;
//       });
//       nowSit = firstChildSit;
//     };
//     if (!$watcher[items]) {
//       $watcher[depName][items] = [];
//     }
//     $watcher[depName][items].push(fun);
//   } else if (preTreatmentResult.v_if) {
//     // 记录这个标记v-if的container的位置
//     let sit = rootContainer.children.length;
//     const { path } = preTreatmentResult.v_if;
//     let data = getGoalData(this.$data, path);
//     let container: PIXI.Container;
//     if (data) {
//       elementStack.push(subEle);
//       container = dealWithContainer.call(this, subEle, scope);
//       rootContainer.addChild(container);
//       containerStack.push(container);
//     }
//     let fun: Function = () => {
//       if (getGoalData(this.$data, path) && !data) {
//         container = forEachCom.call(this, element, scope);
//         rootContainer.addChildAt(container, sit);
//       } else if (!getGoalData(this.$data, path) && data) {
//         rootContainer.removeChild(container);
//       }
//       data = getGoalData(this.$data, path);
//     };
//     if (!$watcher[path]) {
//       $watcher[depName][path] = [];
//     }
//     $watcher[depName][path].push(fun);
//   } else {
//     elementStack.push(subEle);
//     let container = dealWithContainer.call(this, subEle, scope);
//     rootContainer.addChild(container);
//     containerStack.push(container);
//   }
// }

// /**
//  *
//  * @param rootEle template下的第一个元素，（注：和vue一样template的子元素只有一个）
//  * @param { Scope } scope 作用域参数
//  * 例： "item in items"
//  * 如果作用域参数存在，则在作用域内使用item就相当于
//  * 使用getGoalData(items)[item];
//  */
// function forEachCom(
//   this: PixijsvueComponent,
//   rootEle: Element | HTMLElement,
//   scope?: Scope
// ) {
//   let stack: Array<Element> = [];
//   let containerStack: Array<PIXI.Container> = [];
//   let rootContainer = dealWithContainer.call(this, rootEle, scope);

//   if (rootEle.children.length == 0) {
//     return rootContainer;
//   }
//   stack.push(rootEle);
//   containerStack.push(rootContainer);
//   while (stack.length != 0) {
//     let item: Element = <Element>stack.pop();
//     let containerItem: PIXI.Container = <PIXI.Container>containerStack.pop();
//     // 该元素有没有子元素
//     if (item.children.length != 0) {
//       Object.values(item.children).forEach((ele: Element) => {
//         linkContainer.call(
//           this,
//           containerItem,
//           ele,
//           containerStack,
//           stack,
//           scope
//         );
//       });
//     }
//   }
//   return rootContainer;
// }
// export { forEachCom };
